package fr.paulmasson.jfreex.channels;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Scanner;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


public class ChannelInfo {


	private String url = "http://www.guidetele.com/programmes-tv/chaine/@CHANNEL@/@BOUQUET@/soiree/@DATE@";
	private long currentTime;

	public Info currentChannelInfo;
	public Info currentChannelInfoNext;
	private Calendar c;
	

	public String getSourceOfWebPage(String url_page) throws MalformedURLException, IOException {
		URLConnection urlConnection = new URL(url_page).openConnection();
		urlConnection.connect();
		Scanner scanner = new Scanner(urlConnection.getInputStream());
		StringBuffer source = new StringBuffer();
		while (scanner.hasNextLine())
		{
			source.append(scanner.nextLine()+"\n");
		}
		scanner.close();
		return source.toString();
	}


	public ArrayList<Info> getCurrentTrack(LiveChannel channel, long time) throws CantRetrieveInfo {
		currentChannelInfo = new Info(channel.getTitle(),"","",0,0);
		currentChannelInfoNext = new Info(channel.getTitle(),"","",0,0);
		int code = CantRetrieveInfo.OK;
		if (channel.getNum() != -1) {
			try {
				c = Calendar.getInstance();
				c.clear();
				c.setTimeInMillis(time);
//				currentTime = Calendar.getInstance().getTimeInMillis();
				currentTime = time;
				File tmp = File.createTempFile("jfreetv", "xml");

				FileWriter fstream = new FileWriter(tmp);
				BufferedWriter out = new BufferedWriter(fstream);
				System.out.println(url
						.replaceFirst("@BOUQUET@", channel.getBunch())
						.replaceFirst("@CHANNEL@", ""+channel.getNum())
						.replaceFirst("@DATE@", 
								String.format("%04d-%02d-%02d",
										c.get(Calendar.YEAR),
										c.get(Calendar.MONTH)+1,
										c.get(Calendar.DAY_OF_MONTH)
								)));
				String res = getSourceOfWebPage(url
						.replaceFirst("@BOUQUET@", channel.getBunch())
						.replaceFirst("@CHANNEL@", ""+channel.getNum())
						.replaceFirst("@DATE@", 
								String.format("%04d-%02d-%02d",
										c.get(Calendar.YEAR),
										c.get(Calendar.MONTH)+1,
										c.get(Calendar.DAY_OF_MONTH)
								)));
				out.write(res.
						replaceFirst("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">", "").
						replaceAll("<param name=\"movie\" value=\"/medias/sites/guidetele/img/horloge.swf\">","").
						replaceAll("<param name=\"quality\" value=\"high\">",""). 
						replaceAll("<div class=.*hour..>(.*)</div>&nbsp;", "$1 ").
						replaceAll("<br />&nbsp;", " ").
						replaceAll("&nbsp;", " ").
						replaceAll("<br />","").
						replaceAll("&", "et"));
				out.close();
				SAXParserFactory fabrique = SAXParserFactory.newInstance();
				SAXParser parseur = fabrique.newSAXParser();

				DefaultHandler gestionnaire = new XmlHandler();
				try {
					parseur.parse(tmp,gestionnaire);
				} catch (Exception e) {		
					e.printStackTrace();	
				}
			} catch (IOException e) {
				if (CantRetrieveInfo.code500.matcher(e.toString()).find()) {
					code = CantRetrieveInfo.INVALID_URL;
				}
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			}
		}
		if (code != CantRetrieveInfo.OK) {
			throw new CantRetrieveInfo(code);
		}
		ArrayList<Info> res = new ArrayList<Info>();
		res.add(currentChannelInfo);
		res.add(currentChannelInfoNext);
		return res;
	 }



	private long stringHourToLong(int year, int month, int day, String hour) {
		String[] data = hour.split("h");
		Calendar c = Calendar.getInstance();
		c.clear();
		c.set(year, month, day, Integer.parseInt(data[0]), Integer.parseInt(data[1]));
		return c.getTimeInMillis();
	}

	private class XmlHandler extends DefaultHandler{

		private boolean inProgram;
		private int i= 0;



		// simple constructeur
		public XmlHandler(){
			super();
		}



		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			if (qName.equals("div")
					&& attributes.getValue("class")!= null 
					&& (attributes.getValue("class").equals("content")))  {
				i++;
			}
			if (qName.equals("td") 
					&& attributes.getValue("class")!= null) {
				String att = attributes.getValue("class").replaceAll(" ", "");
				inProgram = (att.equals("program") 
						|| att.equals("programshort")
						|| att.equals("programlast")
						|| att.equals("programprevious")
						|| att.equals("programshortprevious")
						|| att.equals("programshortlast"));
			} else if (inProgram 
					&& qName.equals("a")
					&& attributes.getValue("class")!= null 
					&& attributes.getValue("class").equals("details")) {
				String data = attributes.getValue("onMouseover")
				.replaceAll("[ \t\n\f\r]+showmenu\\('", "")
				.replaceAll("'\\)","")
				.replaceAll("\n", "")
				.replaceAll(" Showview : [0-9]+", "")
				.replaceAll("\\\\'", "'")
				.replaceAll(" ( )+", "");
				String [] splitted = data.split("','");
				String [] splitted2 = splitted[0].split(" ", 2);
				String [] splitted3 = splitted2[0].split("-");

				long start = stringHourToLong(c.get(Calendar.YEAR),
						c.get(Calendar.MONTH),
						c.get(Calendar.DAY_OF_MONTH),splitted3[0]);
				long end = stringHourToLong(c.get(Calendar.YEAR),
						c.get(Calendar.MONTH),
						c.get(Calendar.DAY_OF_MONTH),splitted3[1]);

				String desc = splitted2[1];
				String title_local = splitted[1];
				if (i==6) {
					if (start>end) {
						start -= 24*60*60*1000;
					}

				} else if (i==5) {
					if (start>end) {
						end += 24*60*60*1000;
					}
				}

				if (start <= currentTime && currentTime < end) {
					currentChannelInfo = new Info(currentChannelInfo.getChannel(),title_local,desc,start,end);
				} else if (start >= currentTime && currentChannelInfoNext.getStart()==0) {
					currentChannelInfoNext = new Info(currentChannelInfo.getChannel(),title_local,desc,start,end);					
				}
				
			}
		}

		public void endElement(String uri, String localName, String qName) throws SAXException {
			inProgram = !qName.equals("td");
		}

		public void characters(char[] ch,int start, int length) 	throws SAXException{ 
		}

		public void startDocument() throws SAXException {
		}

		public void endDocument() throws SAXException {

		}
	}


}
